package com.budwk.app.uc.controllers;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import com.budwk.app.base.gmpass.SM2Util;
import com.budwk.app.base.gmpass.SM4Util;
import com.budwk.app.common.config.AppException;
import com.budwk.app.jim.server.JimJwtTokenUtils;
import com.budwk.app.sms.service.OpaSmsService;
import com.budwk.app.sqfw.constants.SqfwVerifyCodeTypeConstants;
import com.budwk.app.sqfw.models.Sqfw_verifyCode;
import com.budwk.app.sqfw.services.SqfwPoUserService;
import com.budwk.app.sqfw.services.SqfwVerifyCodeService;
import com.budwk.app.sys.models.*;
import com.budwk.app.sys.services.*;
import com.budwk.app.thirdLogin.ChinaMobileThirdService;
import com.budwk.app.uc.services.AuthService;
import com.budwk.app.uc.services.ValidateService;
import com.budwk.app.util.JwtUtil;
import com.budwk.app.util.RSAUtil;
import com.budwk.starter.common.constant.GlobalConstant;
import com.budwk.starter.common.constant.RedisConstant;
import com.budwk.starter.common.enums.Validation;
import com.budwk.starter.common.exception.BaseException;
import com.budwk.starter.common.openapi.annotation.*;
import com.budwk.starter.common.result.Result;
import com.budwk.starter.common.result.ResultCode;
import com.budwk.starter.log.annotation.SLog;
import com.budwk.starter.log.enums.LogType;
import com.budwk.starter.security.utils.SecurityUtil;
import com.budwk.starter.sms.enums.SmsType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.nutz.aop.interceptor.async.Async;
import org.nutz.dao.Chain;
import org.nutz.dao.Cnd;
import org.nutz.dao.Sqls;
import org.nutz.dao.sql.Sql;
import org.nutz.integration.jedis.RedisService;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.json.Json;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.nutz.mvc.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author wizzer@qq.com
 */
@IocBean
@At("/ucenter/auth")
@SLog(tag = "用户认证")
@ApiDefinition(tag = "用户认证")
@Slf4j
public class AuthController {

    @Inject
    private AuthService authService;

    @Inject
    private ValidateService validateService;

    @Inject
    private SysUserService sysUserService;

    @Inject
    private SysUnitService sysUnitService;

    @Inject
    private SysConfigService sysConfigService;

    @Inject
    private SysMsgService sysMsgService;

    @Inject
    private RedisService redisService;

    @Inject
    private SysAppService sysAppService;

    @Inject
    private SqfwPoUserService sqfwPoUserService;

    @Inject
    private SqfwVerifyCodeService sqfwVerifyCodeService;

    @Inject
    private ChinaMobileThirdService chinaMobileThirdService;

    @Inject
    private OpaSmsService opaSmsService;

    @Inject
    private SysUserSecurityService sysUserSecurityService;

    @Inject
    private SysUserPwdService sysUserPwdService;

    @Inject
    private SysRoleUserService sysRoleUserService;

    @At
    @Ok("json")
    @GET
    @ApiOperation(name = "获取RSA密钥", description = "获取RSA密钥")
    @ApiImplicitParams
    @ApiResponses
    public Result<?> rsa() {
        RSA rsa = new RSA();
        String rsaKey = R.UU32();
        String privateKey = rsa.getPrivateKeyBase64();
        String publicKey = rsa.getPublicKeyBase64();
        redisService.setex(RedisConstant.PRE + "ucenter:rsa:" + rsaKey, 3600, Json.toJson(NutMap.NEW().addv("privateKey", privateKey).addv("publicKey", publicKey)));
        return Result.data(NutMap.NEW().addv("rsaKey", rsaKey).addv("rsaPublicKey", publicKey));
    }

    @At
    @Ok("json")
    @POST
    @SLog(type = LogType.LOGIN, value = "密码、短信验证码同时使用")
    @ApiOperation(name = "用户登录", description = "密码、短信验证码同时使用")
    @ApiFormParams(
            {
                    @ApiFormParam(name = "loginname", description = "用户名"),
                    @ApiFormParam(name = "password", description = "登录密码"),
                    @ApiFormParam(name = "mobile", description = "手机号码", check = true, validation = Validation.MOBILE),
                    @ApiFormParam(name = "smscode", description = "短信验证码"),
                    @ApiFormParam(name = "appId", description = "当前登录的应用ID"),
                    @ApiFormParam(name = "rsaKey", description = "RSA一次性key"),
                    @ApiFormParam(name = "deviceId", description = "设备标识")

            }
    )
    @ApiResponses
    public Result<?> loginByPassWordAndSmsCode(@Param("loginname") String loginname,
                           @Param("password") String password,
                           @Param("mobile") String mobile,
                           @Param("smscode") String smscode,
                           @Param("appId") String appId,
                           @Param("rsaKey") String rsaKey,
                           @Param("authDeviceType") String authDeviceType,
                           @Param("authDeviceId") String authDeviceId, HttpServletRequest req) throws Exception {
        List<Sys_app> appList = sysAppService.listEnable();
        boolean hasApp = false;
        for (Sys_app app : appList) {
            if (Strings.sNull(appId).equals(app.getId())) {
                hasApp = true;
                break;
            }
        }
        if (!hasApp) {
            return Result.error("应用不存在或未启用");
        }
        Sys_user user = null;
        Sys_user_security security = sysUserService.getUserSecurity();
        String rsaDeviceType = "";
        String rsaDeviceId = "";
        authService.checkLoginName(loginname, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());

        //使用SM2解密
        String sm2Pass = SM2Util.decrypt(rsaKey, password);
        rsaDeviceType = SM2Util.decrypt(rsaKey, authDeviceType);
        if (Strings.isNotBlank(authDeviceId)) {
            rsaDeviceId = SM2Util.decrypt(rsaKey, authDeviceId);
        }
        //authService.checkMobile(mobile, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
        //validateService.checkSMSCode(mobile, smscode);
        // 首先校验验证码是否有效 是否过期
        Sqfw_verifyCode checkVerifyCode = sqfwVerifyCodeService.checkCode(mobile, smscode, SqfwVerifyCodeTypeConstants.login_verify_code);
        if (checkVerifyCode == null) return Result.error("验证码输入错误");

        user = sysUserService.loginByPassword(loginname, sm2Pass);
        if (user == null) {
            throw new BaseException("用户登录失败,用户名或密码错误");
        }
        // 修改该验证码已经消费过
        checkVerifyCode.setUsedFlag(true);
        checkVerifyCode.setConsumeTime(new Date());
        sqfwVerifyCodeService.update(checkVerifyCode);

        if (rsaDeviceType.equals("mobile")) {
            //校验DiviceId是否变化
            sysUserService.verifySM4DeviceId(authDeviceId, rsaDeviceId, user);
        }
        //互斥登录
        StpUtil.login(user.getId());
        StpUtil.checkLogin();
        String thisToken = StpUtil.getTokenValue();
        // UserSessionOnlyOne=true 将其他token踢下线
        if (security != null && security.getUserSessionOnlyOne() != null && security.getUserSessionOnlyOne()) {
            for (String token : StpUtil.getTokenValueListByLoginId(user.getId())) {
                if (!thisToken.equals(token)) {
                    StpUtil.logoutByTokenValue(token);
                    // webscoket 下线通知
                    sysMsgService.wsSendMsg(user.getId(), token, Json.toJson(NutMap.NEW().addv("action", "offline")));
                }
            }
        }

        sysUserService.setLoginInfo(user.getId(), Lang.getIP(req));
        SaSession session = StpUtil.getSession(true);
        session.set("id", Strings.sNull(user.getId()));
        session.set("loginname", Strings.sNull(user.getLoginname()));
        session.set("username", Strings.sNull(user.getUsername()));
        session.set("appId", Strings.sNull(appId));
        session.set("unitId", Strings.sNull(user.getUnitId()));
        session.set("unitPath", Strings.sNull(user.getUnitPath()));
        session.set("unitName", Strings.sNull(user.getUnitName()));
        //登录用户所属区域
        session.set("province", Strings.sNull(user.getProvince()));
        session.set("city", Strings.sNull(user.getCity()));
        session.set("district", Strings.sNull(user.getDistrict()));
        session.set("county", Strings.sNull(user.getCounty()));
        session.set("community", Strings.sNull(user.getCommunity()));


        Sys_unit unit = sysUnitService.getMasterCompany(user.getUnitId());
        session.set("masterId", unit == null ? "" : unit.getId());
        session.set("masterPath", unit == null ? "" : unit.getPath());

        // wzy 2023-05-10 查询用户对应的泡泡用户id
        String popoUserId = sqfwPoUserService.getPopoUserIdBySysUserId(user.getId());
        if (StringUtils.isNotBlank(popoUserId)) session.set("popoUid", popoUserId);
        String jimJwtToken = JimJwtTokenUtils.createJwtToken(user.getId(), user.getLoginname());
        if (StringUtils.isNotBlank(popoUserId)) session.set("jimJwtToken", jimJwtToken);

        return Result.success().addData(StpUtil.getTokenInfo().getTokenValue());
    }


    @At
    @Ok("json")
    @POST
    @SLog(type = LogType.LOGIN, value = "登录方式: ${type=='password'?'账号密码':'短信验证码'}")
    @ApiOperation(name = "用户登录", description = "密码登录或短信验证码登录")
    @ApiFormParams(
            {
                    @ApiFormParam(name = "loginname", description = "用户名"),
                    @ApiFormParam(name = "password", description = "登录密码"),
                    @ApiFormParam(name = "mobile", description = "手机号码", check = true, validation = Validation.MOBILE),
                    @ApiFormParam(name = "type", description = "登录方式", example = "mobile-短信验证码登录/password-用户名密码登录"),
                    @ApiFormParam(name = "captchaKey", description = "验证码Key"),
                    @ApiFormParam(name = "captchaCode", description = "验证码"),
                    @ApiFormParam(name = "smscode", description = "短信验证码"),
                    @ApiFormParam(name = "appId", description = "当前登录的应用ID"),
                    @ApiFormParam(name = "rsaKey", description = "RSA一次性key"),
                    @ApiFormParam(name = "deviceId", description = "设备标识")

            }
    )
    @ApiResponses
    public Result<?> login(@Param("loginname") String loginname,
                           @Param("password") String password,
                           @Param("mobile") String mobile,
                           @Param("type") String type,
                           @Param("userName") String userName,
                           @Param("captchaKey") String captchaKey,
                           @Param("captchaCode") String captchaCode,
                           @Param("smscode") String smscode,
                           @Param("appId") String appId,
                           @Param("rsaKey") String rsaKey,
                           @Param("authDeviceType") String authDeviceType,
                           @Param("authDeviceId") String authDeviceId, HttpServletRequest req) throws Exception {
        List<Sys_app> appList = sysAppService.listEnable();
        boolean hasApp = false;
        for (Sys_app app : appList) {
            if (Strings.sNull(appId).equals(app.getId())) {
                hasApp = true;
                break;
            }
        }
        if (!hasApp) {
            return Result.error("应用不存在或未启用");
        }
        Sys_user user = null;
        Sys_user_security security = sysUserService.getUserSecurity();
        String rsaDeviceType = "";
        String rsaDeviceId = "";
        if ("password".equalsIgnoreCase(type)) {
            authService.checkLoginName(loginname, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());

            //使用SM2解密
            String sm2Pass = SM2Util.decrypt(rsaKey, password);
            rsaDeviceType = SM2Util.decrypt(rsaKey, authDeviceType);
            if (Strings.isNotBlank(authDeviceId)) {
                rsaDeviceId = SM2Util.decrypt(rsaKey, authDeviceId);
            }
            user = authService.loginByPassword(loginname, sm2Pass, captchaKey, captchaCode);

            if (rsaDeviceType.equals("mobile")) {
                //校验DiviceId是否变化
                sysUserService.verifySM4DeviceId(authDeviceId, rsaDeviceId, user);
            }
        } else if ("mobile".equalsIgnoreCase(type)) {
            authService.checkMobile(mobile, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
            user = authService.loginByMobile(mobile, smscode);
        } else if ("register".equalsIgnoreCase(type)) {
            try {
                validateService.checkCode(captchaKey, captchaCode);
                String sm2Pass = SM2Util.decrypt(rsaKey, password);
                user = new Sys_user();
                user.setLoginname(loginname);
                user.setUsername(userName);
                user.setPassword(sm2Pass);
                user.setMobile(loginname);
                user = authService.registerUser(user);
            } catch (Exception e) {
                return Result.error(e.getMessage());
            }
        } else {
            throw new BaseException("请求方式不正确");
        }
        if (user == null) {
            throw new BaseException("用户登录失败");
        }
        //互斥登录
        StpUtil.login(user.getId());
        StpUtil.checkLogin();
        String thisToken = StpUtil.getTokenValue();
        // UserSessionOnlyOne=true 将其他token踢下线
        if (security != null && security.getUserSessionOnlyOne() != null && security.getUserSessionOnlyOne()) {
            for (String token : StpUtil.getTokenValueListByLoginId(user.getId())) {
                if (!thisToken.equals(token)) {
                    StpUtil.logoutByTokenValue(token);
                    // webscoket 下线通知
                    sysMsgService.wsSendMsg(user.getId(), token, Json.toJson(NutMap.NEW().addv("action", "offline")));
                }
            }
        }

        sysUserService.setLoginInfo(user.getId(), Lang.getIP(req));
        SaSession session = StpUtil.getSession(true);
        session.set("id", Strings.sNull(user.getId()));
        session.set("loginname", Strings.sNull(user.getLoginname()));
        session.set("username", Strings.sNull(user.getUsername()));
        session.set("appId", Strings.sNull(appId));
        session.set("unitId", Strings.sNull(user.getUnitId()));
        session.set("unitPath", Strings.sNull(user.getUnitPath()));
        session.set("unitName", Strings.sNull(user.getUnitName()));
        //登录用户所属区域
        session.set("province", Strings.sNull(user.getProvince()));
        session.set("city", Strings.sNull(user.getCity()));
        session.set("district", Strings.sNull(user.getDistrict()));
        session.set("county", Strings.sNull(user.getCounty()));
        session.set("community", Strings.sNull(user.getCommunity()));


        Sys_unit unit = sysUnitService.getMasterCompany(user.getUnitId());
        session.set("masterId", unit == null ? "" : unit.getId());
        session.set("masterPath", unit == null ? "" : unit.getPath());

        // wzy 2023-05-10 查询用户对应的泡泡用户id
        String popoUserId = sqfwPoUserService.getPopoUserIdBySysUserId(user.getId());
        if (StringUtils.isNotBlank(popoUserId)) session.set("popoUid", popoUserId);
        String jimJwtToken = JimJwtTokenUtils.createJwtToken(user.getId(), user.getLoginname());
        if (StringUtils.isNotBlank(popoUserId)) session.set("jimJwtToken", jimJwtToken);

        return Result.success().addData(StpUtil.getTokenInfo().getTokenValue());
    }


    // wzy 2023-07-10 现在使用的短信验证码登陆的接口
    @At
    @Ok("json")
    @POST
    @ApiOperation(name = "短信验证码登陆", description = "短信验证码登陆")
    @ApiResponses
    public Result<?> verifyCodeLogin(
            @Param("appId") String appId,
            @Param("phoneNo") String phoneNo,
            @Param("verifyCode") String verifyCode,
            @Param("rsaKey") String rsaKey,
            @Param("authDeviceType") String authDeviceType,
            @Param("authDeviceId") String authDeviceId, HttpServletRequest req) {
        Sys_user user = null;
        Sys_user_security security = sysUserService.getUserSecurity();

        /*String str = redisService.get(RedisConstant.PRE + "ucenter:rsa:" + rsaKey);
        if (Strings.isBlank(str)) {
            throw new BaseException("RSA密钥获取失败");
        }
        NutMap nutMap = Json.fromJson(NutMap.class, str);
        RSA rsa = new RSA(nutMap.getString("privateKey"), nutMap.getString("publickKey"));
        String rsaDeviceId = rsa.decryptStr(authDeviceId, KeyType.PrivateKey);*/

        authService.checkMobile(phoneNo, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());

        // wzy 2024-05-16 带有“测1”的账户不发送验证码
        sysUserService.checkTestUsername(phoneNo);

        // 首先校验验证码是否有效 是否过期
        Sqfw_verifyCode checkVerifyCode = sqfwVerifyCodeService.checkCode(phoneNo, verifyCode, SqfwVerifyCodeTypeConstants.login_verify_code);
        if (checkVerifyCode == null) return Result.error("验证码输入错误");

        // 修改该验证码已经消费过
        checkVerifyCode.setUsedFlag(true);
        checkVerifyCode.setConsumeTime(new Date());
        sqfwVerifyCodeService.update(checkVerifyCode);

        try {
            user = sysUserService.getUserByLoginname(phoneNo);
        } catch (Exception e) {
            return Result.error("账号尚未获得授权,请联系街道管理员获得授权");
        }


        //Sys_user user=sysUserService.getUserByLoginname(loginname);
        //使用SM2解密
        //String sm2Pass=SM2Util.decrypt(rsaKey,password);
        String rsaDeviceType = SM2Util.decrypt(rsaKey, authDeviceType);
        String rsaDeviceId = "";
        if (Strings.isNotBlank(authDeviceId)) {
            rsaDeviceId = SM2Util.decrypt(rsaKey, authDeviceId);
        }

        if (rsaDeviceType.equals("mobile")) {
            //校验DiviceId是否变化
            sysUserService.verifySM4DeviceId(authDeviceId, rsaDeviceId, user);
        }

        loginCommonSessionHandle(appId, req, user);

        return Result.success().addData(StpUtil.getTokenInfo().getTokenValue());
    }

    // wzy 2023-7-10 重置密码并进行登陆
    @At
    @Ok("json")
    @POST
    @ApiOperation(name = "重置密码并登陆", description = "重置密码并登陆")
    @ApiResponses
    public Result<?> resetPasswordAndLogin(
            @Param("appId") String appId,
            @Param("phoneNo") String phoneNo,
            @Param("verifyCode") String verifyCode,
            @Param("newPassword") String newPassword,
            @Param("newPasswordConfirm") String newPasswordConfirm, HttpServletRequest req) {

        if (!newPassword.equals(newPasswordConfirm)) return Result.error("密码不一致");

        Sys_user user = null;
        // 首先校验验证码是否有效 是否过期
        Sqfw_verifyCode checkVerifyCode = sqfwVerifyCodeService.checkCode(phoneNo, verifyCode, SqfwVerifyCodeTypeConstants.rest_password);
        if (checkVerifyCode == null) return Result.error("验证码输入错误");

        // 修改该验证码已经消费过
        checkVerifyCode.setUsedFlag(true);
        checkVerifyCode.setConsumeTime(new Date());
        sqfwVerifyCodeService.update(checkVerifyCode);

        try {
            user = sysUserService.getUserByLoginname(phoneNo);
        } catch (Exception e) {
            return Result.error("手机号不存在");
        }
        // 更改用户的密码
        sysUserService.resetPwd(user.getId(), newPassword, false);

        loginCommonSessionHandle(appId, req, user);
        return Result.success().addData(StpUtil.getTokenInfo().getTokenValue());
    }


    @At("/resetPasswordAndLoginNew")
    @Ok("json")
    @POST
    @ApiOperation(name = "重置密码并登陆(加密)", description = "重置密码并登陆(加密)")
    @ApiResponses
    public Result<?> resetPasswordAndLoginNew(
            @Param("appId") String appId,
            @Param("phoneNo") String phoneNo,
            @Param("newPassword") String newPassword,
            @Param("newPasswordConfirm") String newPasswordConfirm,
            @Param("rsaKey") String rsaKey, HttpServletRequest req) {

        String sm2PassNew = SM2Util.decrypt(rsaKey, newPassword);
        String sm2PassConfirm = SM2Util.decrypt(rsaKey, newPasswordConfirm);

       /* String str = redisService.get(RedisConstant.PRE + "ucenter:rsa:" + rsaKey);
        NutMap nutMap = Json.fromJson(NutMap.class, str);
        RSA rsa = new RSA(nutMap.getString("privateKey"), nutMap.getString("publickKey"));
        String newPasswordNew = rsa.decryptStr(newPassword, KeyType.PrivateKey);
        String newPasswordConfirmNew = rsa.decryptStr(newPasswordConfirm, KeyType.PrivateKey);*/

        if (!sm2PassNew.equals(sm2PassConfirm)) return Result.error("密码不一致");

        Sys_user user = null;

        try {
            user = sysUserService.getUserByLoginname(phoneNo);
        } catch (Exception e) {
            return Result.error("手机号不存在");
        }
        // 更改用户的密码
        sysUserService.resetPwd(user.getId(), sm2PassNew, false);

        loginCommonSessionHandle(appId, req, user);
        return Result.success().addData(StpUtil.getTokenInfo().getTokenValue());
    }


    // wzy 2023-7-10 一键登陆
    @At
    @Ok("json")
    @POST
    @ApiOperation(name = "一键登陆", description = "一键登陆")
    @ApiResponses
    public Result<?> phoneNoDirectLogin(@Param("phoneToken") String phoneToken,
                                        @Param("rsaKey") String rsaKey,
                                        @Param("authDeviceType") String authDeviceType,
                                        @Param("authDeviceId") String authDeviceId, HttpServletRequest req) {

        if (StringUtils.isBlank(phoneToken)) return Result.error("phoneToken不能为空!");

        // 使用token直接调用第三方一键登陆接口获取用户手机号
        String phoneNo = chinaMobileThirdService.parseTokenToPhone(phoneToken);
        if (StringUtils.isBlank(phoneNo)) return Result.error("手机号获取失败");

        Sys_user user = null;
        try {
            user = sysUserService.getUserByLoginname(phoneNo);
        } catch (Exception e) {
            return Result.error("账号尚未获得授权,请联系街道管理员获得授权");
        }

        //使用SM2解密
        //String sm2Pass=SM2Util.decrypt(rsaKey,password);
        String rsaDeviceType = SM2Util.decrypt(rsaKey, authDeviceType);
        String rsaDeviceId = "";
        if (Strings.isNotBlank(authDeviceId)) {
            rsaDeviceId = SM2Util.decrypt(rsaKey, authDeviceId);
        }

        if (rsaDeviceType.equals("mobile")) {
            //校验DiviceId是否变化
            sysUserService.verifySM4DeviceId(authDeviceId, rsaDeviceId, user);
        }


        String appId = "PLATFORM";
        loginCommonSessionHandle(appId, req, user);
        return Result.success().addData(StpUtil.getTokenInfo().getTokenValue());
    }


    @At("/check/getNewToken")
    @Ok("json")
    @GET
    @ApiOperation(name = "更新token")
    @ApiResponses
    @SaCheckLogin
    public Result getNewToken() {
        Result result = Result.NEW();

        StpUtil.login(SecurityUtil.getUserId());
        //stp生成token

        //获取token值
        String token = StpUtil.getTokenInfo().tokenValue;
        //StpUtil.setTokenValue(token, 1);

        //更新token时长
        StpUtil.setTokenValue(token, 259200);

        result.addData(token);
        return result;
    }


    @At
    @Ok("json")
    @GET
    @ApiOperation(name = "获取验证码", description = "图形验证码")
    @ApiImplicitParams
    @ApiResponses(
            {
                    @ApiResponse(name = "key", description = "验证码的一次性key"),
                    @ApiResponse(name = "code", description = "验证码值")
            }
    )
    public Result<?> captcha() {
        return validateService.getCaptcha();
    }

    @At
    @Ok("json")
    @GET
    @ApiOperation(name = "检查密码是否需要修改", description = "检查密码是否需要修改")
    @ApiFormParams
    @ApiResponses
    @SaCheckLogin
    public Result<?> checkpwd() throws BaseException {
        Sys_user user = sysUserService.getUserById(SecurityUtil.getUserId());
        if (user != null) {
            if (user.isNeedChangePwd()) {
                return Result.success().addData("您的密码还是初始密码，请修改密码！");
            }
            try {
                sysUserService.checkPwdTimeout(user.getId(), user.getPwdResetAt());
            } catch (BaseException e) {
                return Result.success().addData("您的密码已过期，请及时修改密码！");
            }
        }
        return Result.success();
    }

    @At
    @Ok("json")
    @POST
    @ApiOperation(name = "获取短信验证码", description = "发送短信验证码")
    @ApiFormParams({
            @ApiFormParam(name = "mobile", description = "手机号码", required = true, check = true, validation = Validation.MOBILE)
    })
    @ApiResponses
    public Result<?> smscode(@Param("mobile") String mobile, HttpServletRequest req) throws BaseException {
        Sys_user_security security = sysUserService.getUserSecurity();
        authService.checkMobile(mobile, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());

        // wzy 2024-05-16 带有“测1”的账户不发送验证码
        sysUserService.checkTestUsername(mobile);

        validateService.getSmsCode(mobile, SmsType.LOGIN);
        return Result.success();
    }

    @At("/check/loginname")
    @Ok("json")
    @POST
    @ApiOperation(name = "检查用户名是否存在")
    @ApiFormParams({
            @ApiFormParam(name = "loginname", description = "用户名", required = true, check = true)
    })
    @ApiResponses
    public Result<?> checkLoginname(@Param("loginname") String loginname, HttpServletRequest req) throws BaseException {
        Sys_user_security security = sysUserService.getUserSecurity();
        Sys_user user = authService.getUserByLoginname(loginname, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
        if (user == null) {
            throw new BaseException("账号尚未获得授权,请联系街道管理员获得授权");
        }
        List<NutMap> typeList = new ArrayList<>();
        if (Strings.isNotBlank(user.getMobile())) {
            typeList.add(NutMap.NEW().addv("key", "mobile").addv("val", "手机号码"));
        }
        if (Strings.isNotBlank(user.getEmail())) {
            typeList.add(NutMap.NEW().addv("key", "email").addv("val", "电子邮箱"));
        }
        return Result.success().addData(typeList);
    }

    @At("/pwd/sendcodeNew")
    @Ok("json")
    @POST
    @ApiOperation(name = "发送重置密码验证码", description = "type=mobile 短信接收验证码,type=email 邮箱接收验证码")
    @ApiFormParams({
            @ApiFormParam(name = "loginname", description = "用户名", required = true, check = true),
            @ApiFormParam(name = "type", description = "验证方式", required = true, check = true)
    })
    @ApiResponses
    public Result<?> sendcodeNew(@Param("loginname") String loginname, @Param("type") String type, HttpServletRequest req) throws BaseException {
        Sys_user_security security = sysUserService.getUserSecurity();
        Sys_user user = authService.getUserByLoginname(loginname, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
        if (user == null) {
            throw new BaseException("账号尚未获得授权,请联系街道管理员获得授权");
        }
        int sendCount = 0;
        if ("mobile".equalsIgnoreCase(type)) {
            sendCount = sqfwVerifyCodeService.commonSendCode(loginname, SqfwVerifyCodeTypeConstants.rest_password);
            if (sendCount <= 0) return Result.error();
        }

        return Result.success(sendCount).addMsg("验证码已发送至手机号码，请注意查收");

    }


    @At("/codeVerify")
    @Ok("json")
    @POST
    @ApiOperation(name = "验证码校验", description = "验证码校验")
    @ApiFormParams({
            @ApiFormParam(name = "loginname", description = "电话号码", required = true, check = true),
            @ApiFormParam(name = "verifyCode", description = "验证码", required = true, check = true)
    })
    @ApiResponses
    public Result<?> codeVerify(@Param("loginname") String loginname, @Param("verifyCode") String verifyCode, HttpServletRequest req) throws BaseException {
        // 首先校验验证码是否有效 是否过期
        Sqfw_verifyCode checkVerifyCode = sqfwVerifyCodeService.checkCode(loginname, verifyCode, SqfwVerifyCodeTypeConstants.rest_password);
        if (checkVerifyCode == null) return Result.error("验证码输入错误");

        // 修改该验证码已经消费过
        checkVerifyCode.setUsedFlag(true);
        checkVerifyCode.setConsumeTime(new Date());
        sqfwVerifyCodeService.update(checkVerifyCode);


        return Result.success();

    }


    @At("/pwd/sendcode")
    @Ok("json")
    @POST
    @ApiOperation(name = "发送重置密码验证码", description = "type=mobile 短信接收验证码,type=email 邮箱接收验证码")
    @ApiFormParams({
            @ApiFormParam(name = "loginname", description = "用户名", required = true, check = true),
            @ApiFormParam(name = "type", description = "验证方式", required = true, check = true)
    })
    @ApiResponses
    public Result<?> pwdSendCode(@Param("loginname") String loginname, @Param("type") String type, HttpServletRequest req) throws BaseException {
        Sys_user_security security = sysUserService.getUserSecurity();
        Sys_user user = authService.getUserByLoginname(loginname, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
        if (user == null) {
            throw new BaseException("账号尚未获得授权,请联系街道管理员获得授权");
        }
        String msg = "";
        if ("mobile".equalsIgnoreCase(type)) {
            validateService.getSmsCode(user.getMobile(), SmsType.PASSWORD);
            msg = "验证码已发送至手机号码，请注意查收";
        }
        if ("email".equalsIgnoreCase(type)) {
            validateService.getEmailCode("您正在重置密码", Strings.trim(loginname), user.getEmail());
            msg = "验证码已发送至Email，请注意查收";
        }
        return Result.success().addMsg(msg);
    }

    @At("/pwd/save")
    @Ok("json")
    @POST
    @SLog(value = "重置密码")
    @ApiOperation(name = "保存重置的新密码")
    @ApiFormParams({
            @ApiFormParam(name = "loginname", description = "用户名", required = true, check = true),
            @ApiFormParam(name = "type", description = "验证方式", required = true, check = true),
            @ApiFormParam(name = "password", description = "新密码", required = true, check = true),
            @ApiFormParam(name = "code", description = "验证码", required = true, check = true)
    })
    @ApiResponses
    public Result<?> pwdSave(@Param("loginname") String loginname, @Param("type") String type,
                             @Param("password") String password, @Param("code") String code, HttpServletRequest req) throws BaseException {
        Sys_user_security security = sysUserService.getUserSecurity();
        Sys_user user = authService.getUserByLoginname(loginname, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
        if (user == null) {
            throw new BaseException("用户不存在");
        }
        if ("mobile".equalsIgnoreCase(type)) {
            validateService.checkSMSCode(user.getMobile(), code);
        } else if ("email".equalsIgnoreCase(type)) {
            validateService.checkEmailCode(Strings.trim(loginname), code);
        } else {
            throw new BaseException("验证方式不正确");
        }
        authService.setPwdByLoginname(loginname, password);
        return Result.success();
    }


    @At
    @Ok("json:{locked:'password|salt|createdBy|createdAt|updatedBy|updatedAt|delFlag',ignoreNull:false}")
    @GET
    @ApiOperation(name = "获取登录用户信息", description = "需登录成功")
    @ApiImplicitParams
    @ApiResponses(
            {
                    @ApiResponse(name = "conf", description = "系统参数", type = "object"),
                    @ApiResponse(name = "user", description = "用户信息", type = "object"),
                    @ApiResponse(name = "token", description = "Token值", type = "object"),
                    @ApiResponse(name = "menus", description = "权限菜单", type = "object"),
                    @ApiResponse(name = "roles", description = "角色列表", type = "object")
            }
    )
    @SaCheckLogin
    public Result<?> info() {
        log.debug("StpUtil.getLoginIdAsString():::" + StpUtil.getLoginIdAsString());
        Sys_user user = authService.getUserById(StpUtil.getLoginIdAsString());
        NutMap map = NutMap.NEW();
        //获取应用菜单及公共菜单
        map.addv(SecurityUtil.getAppId(), sysUserService.getMenuList(SecurityUtil.getUserId(), SecurityUtil.getAppId()));
        map.addv(GlobalConstant.DEFAULT_COMMON_APPID, sysUserService.getMenuList(SecurityUtil.getUserId(), GlobalConstant.DEFAULT_COMMON_APPID));
        return Result.data(NutMap.NEW()
                .addv("conf", sysConfigService.getMapAll(SecurityUtil.getAppId()))
                .addv("user", user)
                .addv("token", StpUtil.getTokenInfo())
                .addv("apps", sysUserService.getAppList(SecurityUtil.getUserId()))
                .addv("permissions", sysUserService.getPermissionList(SecurityUtil.getUserId()))
                .addv("menus", map)
                .addv("roles", sysUserService.getRoleList(SecurityUtil.getUserId()))
                .addv("popoUid", sqfwPoUserService.getPopoUserIdBySysUserId(user.getId()))
                .addv("webSocketToken", JimJwtTokenUtils.createJwtToken(user.getId(), user.getLoginname())));
    }

    @At
    @Ok("json")
    @POST
    @ApiOperation(name = "设置自定义布局")
    @ApiFormParams({
            @ApiFormParam(name = "themeConfig", description = "配置内容", example = "{}")
    })
    @ApiResponses
    public Result<?> theme(@Param("themeConfig") String themeConfig) {
        if (GlobalConstant.DEFAULT_SYSADMIN_LOGINNAME.equals(SecurityUtil.getUserLoginname()) && sysConfigService.getBoolean(SecurityUtil.getAppId(), "AppDemoEnv")) {
            return Result.error(ResultCode.DEMO_ERROR);
        }
        sysUserService.setThemeConfig(SecurityUtil.getUserId(), themeConfig);
        return Result.success();
    }

    @At
    @Ok("json:{locked:'password|salt',ignoreNull:false}")
    @GET
    @ApiOperation(name = "获取系统参数", description = "获取系统参数")
    @ApiImplicitParams(
            {
                    @ApiImplicitParam(name = "appId", description = "应用ID", required = true, check = true)
            }
    )
    @ApiResponses
    public Result<?> conf(@Param("appId") String appId) {
        return Result.data(sysConfigService.getMapOpened(appId));
    }

    @At
    @GET
    @SLog(type = LogType.LOGIN, value = "退出登录")
    @Ok("json")
    @ApiOperation(name = "退出登录")
    @ApiImplicitParams
    @ApiResponses
    @SaCheckLogin
    public Result<?> logout(HttpServletRequest req) {
        String userId = SecurityUtil.getUserId();
        String appId = SecurityUtil.getAppId();
        String username = SecurityUtil.getUserUsername();
        String loginname = SecurityUtil.getUserLoginname();
        StpUtil.logout();
        req.setAttribute("_slog_appid", appId);
        req.setAttribute("_slog_user_id", userId);
        req.setAttribute("_slog_user_username", username);
        req.setAttribute("_slog_user_loginname", loginname);
        return Result.success();
    }

    private void loginCommonSessionHandle(String appId, HttpServletRequest req, Sys_user user) {
        StpUtil.login(user.getId()/*,"mobile"*/);
        StpUtil.checkLogin();

        sysUserService.setLoginInfo(user.getId(), Lang.getIP(req));
        SaSession session = StpUtil.getSession(true);
        session.set("loginname", Strings.sNull(user.getLoginname()));
        session.set("username", Strings.sNull(user.getUsername()));
        session.set("appId", Strings.sNull(appId));
        session.set("unitId", Strings.sNull(user.getUnitId()));
        session.set("unitPath", Strings.sNull(user.getUnitPath()));
        Sys_unit unit = sysUnitService.getMasterCompany(user.getUnitId());
        session.set("masterId", unit == null ? "" : unit.getId());
        session.set("masterPath", unit == null ? "" : unit.getPath());
    }

    /**
     * 祥云小助后台管理发送短信验证码
     * Add by LJT 2023-09-28
     */
    @At("/sendAdminLoginSmsCode")
    @Ok("json")
    @POST
    @ApiOperation(name = "祥云小助后台管理发送短信验证码")
    @ApiFormParams({
            @ApiFormParam(name = "mobile", description = "手机号码", required = true, check = true, validation = Validation.MOBILE)
    })
    @ApiResponses
    public Result<?> sendAdminLoginSmsCode(@Param("mobile") String mobile, HttpServletRequest req) {
        try {
            sysUserService.getUserByLoginname(mobile);
        } catch (Exception e) {
            return Result.error("手机号不存在");
        }
        Sys_user_security security = sysUserService.getUserSecurity();
        authService.checkMobile(mobile, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());

        // wzy 2024-05-16 用户名称中带有"测1"的不进行登录
        sysUserService.checkTestUsername(mobile);

        int smsCount = validateService.getAdminLoginSmsCode(mobile, SqfwVerifyCodeTypeConstants.login_admin_verify_code);
        return Result.success(smsCount);
    }


    /**
     * 祥云小助后台管理用户密码登录
     * Add by LJT 2023-09-28
     */
    @At("/loginForAdmin")
    @Ok("json")
    @POST
    @SLog(type = LogType.LOGIN, value = "登录方式: ${type=='password'?'账号密码':'短信验证码'}")
    @ApiOperation(name = "用户登录", description = "密码登录或短信验证码登录")
    @ApiFormParams(
            {
                    @ApiFormParam(name = "loginname", description = "用户名"),
                    @ApiFormParam(name = "password", description = "登录密码"),
                    @ApiFormParam(name = "mobile", description = "手机号码", check = true, validation = Validation.MOBILE),
                    @ApiFormParam(name = "type", description = "登录方式", example = "mobile-短信验证码登录/password-用户名密码登录"),
                    @ApiFormParam(name = "captchaKey", description = "验证码Key"),
                    @ApiFormParam(name = "captchaCode", description = "验证码"),
                    @ApiFormParam(name = "smscode", description = "短信验证码"),
                    @ApiFormParam(name = "appId", description = "当前登录的应用ID"),
                    @ApiFormParam(name = "rsaKey", description = "RSA一次性key"),
                    @ApiFormParam(name = "deviceId", description = "设备标识")

            }
    )
    @ApiResponses
    public Result<?> loginForAdmin(@Param("loginname") String loginname,
                                   @Param("password") String password,
                                   @Param("mobile") String mobile,
                                   @Param("type") String type,
                                   @Param("captchaKey") String captchaKey,
                                   @Param("captchaCode") String captchaCode,
                                   @Param("smscode") String smscode,
                                   @Param("appId") String appId,
                                   @Param("rsaKey") String rsaKey, HttpServletRequest req) {
        List<Sys_app> appList = sysAppService.listEnable();
        boolean hasApp = false;
        for (Sys_app app : appList) {
            if (Strings.sNull(appId).equals(app.getId())) {
                hasApp = true;
                break;
            }
        }
        if (!hasApp) {
            return Result.error("应用不存在或未启用");
        }
        Sys_user user = null;
        Sys_user_security security = sysUserService.getUserSecurity();
        if ("password".equalsIgnoreCase(type)) {
            authService.checkLoginName(loginname, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
            String str = redisService.get(RedisConstant.PRE + "ucenter:rsa:" + rsaKey);
            if (Strings.isBlank(str)) {
                throw new BaseException("RSA密钥获取失败");
            }
            NutMap nutMap = Json.fromJson(NutMap.class, str);
            RSA rsa = new RSA(nutMap.getString("privateKey"), nutMap.getString("publickKey"));
            String rsaPassword = rsa.decryptStr(password, KeyType.PrivateKey);
            user = authService.loginByPassword(loginname, rsaPassword, captchaKey, captchaCode);
        } else if ("mobile".equalsIgnoreCase(type)) {
            authService.checkMobile(mobile, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
            user = authService.loginByMobile(mobile, smscode);
        } else if ("password&mobile".equalsIgnoreCase(type)) {
            authService.checkLoginName(loginname, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
            String str = redisService.get(RedisConstant.PRE + "ucenter:rsa:" + rsaKey);
            if (Strings.isBlank(str)) {
                throw new BaseException("RSA密钥获取失败");
            }
            NutMap nutMap = Json.fromJson(NutMap.class, str);
            RSA rsa = new RSA(nutMap.getString("privateKey"), nutMap.getString("publickKey"));
            String rsaPassword = rsa.decryptStr(password, KeyType.PrivateKey);
            authService.checkMobile(mobile, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
            user = authService.loginByPasswordAndSmsCode(loginname, rsaPassword, smscode);
        } else {
            throw new BaseException("请求方式不正确");
        }
        if (user == null) {
            throw new BaseException("用户登录失败");
        }

        // 需求产品说放开社区登录限制
       /* Sys_user sysUser = sysUserService.fetch(user.getId());
        if (!"直属".equals(sysUser.getCommunity())) {
            return Result.error("该用户无登录权限！");
        }*/
        StpUtil.login(user.getId());
        StpUtil.checkLogin();
        String thisToken = StpUtil.getTokenValue();

        sysUserService.setLoginInfo(user.getId(), Lang.getIP(req));
        return Result.success().addData(StpUtil.getTokenInfo().getTokenValue());
    }

    @At
    @Ok("json")
    @POST
    public Result<?> getJwtToken() {
        return Result.data(JwtUtil.createToken());
    }

    @At
    @Ok("json")
    @POST
    public Result<?> genTokenByPhone(@Param("phone") String phone, @Param("jwtToken") String jwtToken) throws BaseException {
        if (!JwtUtil.validate(jwtToken)) {
            return Result.error("jwtToken失效");
        }
        Sys_user user = sysUserService.fetch(Cnd.where(Sys_user::getLoginname, "=", phone));
        String token = StpUtil.getTokenValueByLoginId(user.getId());
        if (StrUtil.isEmpty(token)) {
            StpUtil.login(user.getId());
            token = StpUtil.getTokenValue();
        }
        return Result.data(token);

    }

    @At
    @Ok("json")
    @GET
    public Result<?> valitaToken() {
        String userId = SecurityUtil.getUserId();
        Sys_user user = sysUserService.fetch(Cnd.where(Sys_user::getId, "=", userId));
        return Result.data(user);
    }


    @At("/pwd/adminRegister")
    @Ok("json")
    @POST
    @ApiOperation(name = "发送注册验证码", description = "loginname 手机号码")
    @ApiFormParams({
            @ApiFormParam(name = "loginname", description = "手机号码", required = true, check = true),
    })
    @ApiResponses
    public Result<?> adminRegister(@Param("username") String username,
                                   @Param("loginname") String loginname,
                                   @Param("password") String password,
                                   @Param("captchaKey") String captchaKey,
                                   @Param("captchaCode") String captchaCode, HttpServletRequest req) throws BaseException {
        Sys_user user = new Sys_user();
        //this.checkPassword(user, password);
        Sys_unit sys_unit = sysUnitService.fetch("47a2303ef34e49a2882dc62ec2896381");

        String key = null;
        try {
            key = SM4Util.generateKey();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        //序号查询
        Sql sql = Sqls.create("select max(CAST(serialNo as int)) from shequ.sys_user");
        sql.setCallback(Sqls.callback.integer());
        sysUserService.dao().execute(sql);

        //设置用户信息
        String cipher = SM4Util.encryptEcb(key, password);
        user.setUsername(username);
        user.setLoginname(loginname);
        user.setPassword(cipher);
        user.setSm4PassKey(key);
        user.setPassword(cipher);
        user.setSex(user.getSex() == null ? 0 : user.getSex());
        user.setLoginCount(0);
        user.setNeedChangePwd(false);
        user.setUnitId(sys_unit.getId());
        user.setUnit(sys_unit);
        user.setUnitName(sys_unit.getName());
        user.setUnitPath(sys_unit.getPath());
        user.setSerialNo(String.valueOf(sql.getInt() + 1));

        validateService.checkCode(captchaKey, captchaCode);

        Sys_user_security security = sysUserSecurityService.getWithCache();
        if (security != null && security.getHasEnabled() && security.getPwdRepeatCheck() && security.getPwdRepeatNum() > 0) {
            user.setNeedChangePwd(true);
        }
        user.setPwdResetAt(System.currentTimeMillis());
        //  user.setCompanyId(sysUnitService.getMasterCompanyId(user.getUnitId()));
        Sys_user newSysUser = sysUserService.insert(user);

        //插入用户角色表
        sysRoleUserService.insert("shequ.sys_role_user", Chain.make("id", R.UU32()).add("userId", user.getId()).add("roleId", "a04c91721a9841bb9538f1ae1f085043"));
        this.recordPwd(user.getId(), cipher, key);

        return Result.success(newSysUser);

    }


    @Async
    public void recordPwd(String userId, String password, String salt) {
        Sys_user_security security = sysUserSecurityService.getWithCache();
        if (security != null && security.getHasEnabled() && security.getPwdRepeatCheck() && security.getPwdRepeatNum() > 0) {
            Sys_user_pwd userPwd = new Sys_user_pwd();
            userPwd.setUserId(userId);
            userPwd.setPassword(password);
            userPwd.setSm4PassKey(salt);
            userPwd.setSalt(null);
            sysUserPwdService.insert(userPwd);
            Sql sql = Sqls.create("delete from shequ.sys_user_pwd where userId=@userId and id not in(select t.id FROM (SELECT * from shequ.sys_user_pwd where userId=@userId order by createdAt desc limit $num)as t)");
            sql.setParam("userId", userId);
            sql.setVar("num", security.getPwdRepeatNum());
            sysUserPwdService.execute(sql);
        }
    }

    @At("/loginForThird")
    @Ok("json")
    @POST
    @ApiOperation(name = "用户登录", description = "密码登录")
    @ApiFormParams(
            {
                    @ApiFormParam(name = "loginname", description = "用户名"),
                    @ApiFormParam(name = "password", description = "登录密码"),
                    @ApiFormParam(name = "rsaKey", description = "RSA一次性key")
            }
    )
    @ApiResponses
    public Result<?> loginForThird(@Param("phone") String loginname,
                                   @Param("password") String password,
                                   @Param("rsaKey") String rsaKey, HttpServletRequest req) {
        Sys_user user = null;
        Sys_user_security security = sysUserService.getUserSecurity();
        authService.checkLoginName(loginname, Lang.getIP(req), security != null && security.getNameRetryLock(), security == null ? 0 : security.getNameRetryNum(), security == null ? 0 : security.getNameTimeout());
        String str = redisService.get(RedisConstant.PRE + "ucenter:rsa:" + rsaKey);
        if (Strings.isBlank(str)) {
            throw new BaseException("RSA密钥获取失败");
        }
        NutMap nutMap = Json.fromJson(NutMap.class, str);
        RSA rsa = new RSA(nutMap.getString("privateKey"), nutMap.getString("publickKey"));
        String rsaPassword = rsa.decryptStr(password, KeyType.PrivateKey);
        user = authService.loginByPasswordForThird(loginname, rsaPassword);

        if (user == null) {
            throw new BaseException("用户登录失败");
        }

        Sys_user sysUser = sysUserService.fetch(user.getId());
        if (!"直属".equals(sysUser.getCommunity())) {
            return Result.error("该用户无登录权限！");
        }
        StpUtil.login(user.getId());
        StpUtil.checkLogin();
        String thisToken = StpUtil.getTokenValue();
        sysUserService.setLoginInfo(user.getId(), Lang.getIP(req));
        return Result.success().addData(StpUtil.getTokenInfo().getTokenValue());
    }


    @At("/getEncryptByPublic")
    @Ok("json")
    @POST
    @ApiOperation(name = "明文加密", description = "明文加密")
    @ApiFormParams(
            {
                    @ApiFormParam(name = "content", description = "明文内容"),
                    @ApiFormParam(name = "publicKey", description = "公钥")
            }
    )
    @ApiResponses
    public Result<?> getEncryptByPublic(@Param("content") String content, @Param("publicKey") String publicKey, HttpServletRequest req) {
        if (StringUtils.isEmpty(content) || StringUtils.isEmpty(publicKey)) {
            throw new AppException(ResultCode.PARAM_ERROR.getMsg());
        }
        String encryptedText = null;
        try {
            encryptedText = RSAUtil.encryptByPublicKey(publicKey, content);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return Result.data(encryptedText);
    }
}
